package com.wb.iec104.utils;

import java.math.BigInteger;

/**
 * <p>
 * Title: 沙蓄EventLog
 * </p>
 * 
 * <p>
 * Description:
 * </p>
 * 处理字节的一些基本操作
 * <p>
 * Copyright: Copyright (c) 2007
 * </p>
 * 
 * <p>
 * Company: 健新科技
 * </p>
 * 
 * @author 魏明智
 * @version 1.0
 */
public class ByteUtil {
	public ByteUtil() {
	}

	/**
	 * 将字节数组转换为用16进表示的字符串
	 * 
	 * @param buf
	 *            byte[]
	 * @return String
	 */
	public static String toHexString(byte[] buf) {
		String hex = "";
		if (buf == null)
			return hex;
		for (int i = 0; i < buf.length; i++) {
			hex += toHexString(buf[i]);
		}
		return hex;
	}
	/**
	 * 将两字节组装成short型 分为高位和低位，
	 * 第一个参数为高位，第二个参数为低位
	 * @param low 低位
	 *            byte
	 * @param hight 高位
	 *            byte
	 * @return int
	 */
	public static short hex2Short(byte hight, byte low) {
		String value = toHexString(hight) + toHexString(low);
		return Short.parseShort(value, 16);
	} 
	/**
	 * 将四字节组装成long型 分为高位  低位1 低位2 低位3
	 * @param hight
	 * @param lowA
	 * @param lowB
	 * @param lowC
	 * @return long
	 */
	public static long hex2Long(byte hight, byte lowA,byte lowB, byte lowC) {
        String value = toHexString(hight) + toHexString(lowA)+toHexString(lowB)+toHexString(lowC);
        return Long.parseLong(value, 16);
    }
	/**
	 *  将两字节组装成long型 分为高位和低位
	 *  第一个参数为高位，第二个参数为低位
	 * @param hight
	 * @param low
	 * @return long
	 */
    public static long hex2Long(byte hight, byte low) {
        String value = toHexString(hight) + toHexString(low);
        return Long.parseLong(value, 16);
    }
	   /**
     * 左补0
     * @param str
     * @param strLength
     * @return
     */
    public static String addZeroForNum(String str, int strLength) {  
        int strLen = str.length();  
        if (strLen < strLength) {  
            while (strLen < strLength) {  
                StringBuffer sb = new StringBuffer();  
                sb.append("0").append(str);// 左补0  
                // sb.append(str).append("0");//右补0  
                str = sb.toString();  
                strLen = str.length();  
            }  
        }  
        return str;  
    } 
   
	/**
     * 通过byte数组取得float
     * @param b 字节数组
     * @param index 第几位开始取.
     * @return
     */
    public static float hex2Float(byte[] b, int index) {
        int l;
        l = b[index + 0];
        l &= 0xff;
        l |= ((long) b[index + 1] << 8);
        l &= 0xffff;
        l |= ((long) b[index + 2] << 16);
        l &= 0xffffff;
        l |= ((long) b[index + 3] << 24);
        return Float.intBitsToFloat(l);
    }

	/**
	 * 将字节转换为用16进表示的字符串
	 * 
	 * @param buf
	 *            byte
	 * @return String
	 */
	public static String toHexString(byte b) {
		String s = Integer.toHexString(b);
		if (s.length() == 1) {
			s = "0" + s;
		} else if (s.length() > 2) {
			s = s.substring(s.length() - 2);
		}
		return s;
	}

	/**
	 * 将byte当作无符号的字节类型即取值：0..255
	 * 
	 * @param b
	 *            byte
	 * @return int
	 */
	public static int asUnsignedByte(byte b) {
		return Integer.parseInt(toHexString(b), 16);
	}

	/**
	 * 将两字节组装成int型
	 * 
	 * @param low
	 *            byte
	 * @param hight
	 *            byte
	 * @return int
	 */
	public static int valueOf2byte(byte low, byte hight) {
		String value = toHexString(hight) + toHexString(low);
		return Integer.parseInt(value, 16);
	}

	/**
	 * 将字节转换为标准的8位二进制字符串，不足位补0
	 * 
	 * @param b
	 *            byte
	 * @return String
	 */
	public static String toBinaryString(byte b) {
		String bin = Integer.toBinaryString(b);
		int len = bin.length();
		for (int i = len; i < 8; i++)
			bin = "0" + bin;
		return bin;
	}

	/**
	 * 将将字节转换为标准的8位二进制字符串，不足位补0
	 * 和上面方法区别是java是有符号的数，当超过127时，java会将字节按整形处理，现在就是将字节扩展在无符号数，最大处理255
	 * 
	 * @param b
	 * @return
	 */
	public static String toBinaryString2(byte b) {
		StringBuffer sb = new StringBuffer();
		String hex = toHexString(b);
		for (int i = 0; i < hex.length(); i++) {
			String s = String.valueOf(hex.charAt(i));
			String hex1 = Integer.toBinaryString(Integer.parseInt(s, 16));
			for (int j = hex1.length(); j < 4; j++) {
				sb.append("0");
			}
			sb.append(hex1);
		}
		return sb.toString();
	}

	/**
	 * 将字节b转换为二进制数据字符串，然后从startbit开始取len位，转换为整形。 开始位从右(0)到左(7)
	 * 例getBit(0x08,1,1)=0;
	 * 
	 * @param b
	 *            byte
	 * @param startbit
	 *            int
	 * @param len
	 *            int
	 * @return int
	 */
	public static int getBit(byte b, int startbit, int len) {
		String bitStr = toBinaryString(b);
		bitStr = bitStr.substring(8 - startbit - len, 8 - startbit);
		return Integer.parseInt(bitStr, 2);
	}

	/**
	 * 得到字节二进制算术和，不计超过256的值
	 * 
	 * @param buf
	 *            byte[]
	 * @return byte
	 */
	public static byte getCheckCS(byte[] buf, int offset, int len) {
		int b = 0;
		if (buf == null)
			return 0;
		if (len > buf.length)
			len = buf.length;
		for (int i = offset; i < offset + len; i++) {
			b = (byte) (b + buf[i]);
		}
		return (byte) b;
	}

	/**
	 * 清空缓冲区，用0字符填充
	 * 
	 * @param buf
	 *            byte[]
	 */
	public static void clearbuf(byte[] buf) {
		if (buf == null)
			return;
		for (int i = 0; i < buf.length; i++)
			buf[i] = 0;
	}

	/**
	 * 将buf1和buf2组成一个buf返回
	 * 
	 * @param buf1
	 *            byte[]
	 * @param buf2
	 *            byte[]
	 * @param len
	 *            int //从0开始的长度
	 * @return byte[]
	 */
	public static byte[] conj(byte[] buf1, byte[] buf2, int len) {
		if (buf1 == null && buf2 == null)
			return null;
		if (buf2 == null)
			return buf1;
		if (buf2.length < len)
			len = buf2.length;
		int totalLen = len;// 总长度
		int i;
		byte[] buf;
		if (buf1 == null) {
			buf = new byte[totalLen];
			for (i = 0; i < totalLen; i++)
				buf[i] = buf2[i];
		} else {
			totalLen = totalLen + buf1.length;
			buf = new byte[totalLen];
			for (i = 0; i < buf1.length; i++)
				buf[i] = buf1[i];
			for (i = buf1.length; i < totalLen; i++)
				buf[i] = buf2[i - buf1.length];
		}
		return buf;
	}

	/**
	 * 将整形数据转换为字节型数据
	 * 
	 * @param buf
	 *            int[]
	 * @return byte[]
	 */
	public static byte[] toBytes(int[] buf) {
		if (buf == null)
			return null;
		byte[] b = new byte[buf.length];
		for (int i = 0; i < buf.length; i++) {
			b[i] = (byte) buf[i];
		}
		return b;
	}

	/**
	 * 截取一段字节
	 * 
	 * @param buf
	 * @param start
	 *            起始字节
	 * @param len
	 *            长度
	 * @return 截取的字节数组
	 */
	public static byte[] subBytes(byte[] buf, int start, int len) {
		if (null == buf)
			return null;
		if (len < 1)
			return null;
		byte[] bytes = new byte[len];
		for (int i = 0; i < len; i++) {
			bytes[i] = buf[start + i];
		}
		return bytes;
	}

	/**
	 * 将一个int型转换成一个字节数组
	 * 
	 * @param intValue
	 * @param normal
	 * @return
	 */
	public static byte[] integerToBytes(int intValue, boolean normal) {
		byte[] byteValue = new byte[4];
		int shift = 0;

		for (int x = 0; x < 4; x++) {
			shift -= 8;
			if (normal)
				byteValue[x] = (byte) (intValue >>> shift);
			else
				byteValue[3 - x] = (byte) (intValue >>> shift);
		}

		return byteValue;
	}

	/**
	 * 将一个十六进制数转换成一个整数 将VANCOMM遥测中的数据转换成整数 VANCOMM使用值是12个字节
	 * 
	 * @param args
	 */
	public static int bytesToInteger(String value) {
		if (value == null)
			throw new IllegalStateException();
		int i = Integer.parseInt(value, 16);
		byte low = (byte) i;
		byte high = (byte) (i >>> 8);
		int intValue = 0;

		int flag = high & 0x08;
		if (flag == 0)
			high &= (byte) 0x07;
		else {
			high |= (byte) 0xf8;
			high = (byte) (~high);
			low = (byte) (~low);
		}
		intValue |= (high & 0xff);
		intValue <<= 8;
		intValue |= (low & 0xff);

		if (flag == 8) {
			intValue = -(intValue + 1);
		}
		return intValue;
	}

	/**
	 * 将一个字节转换成16进制字符，并截取后转换成整数
	 * 
	 * @param value
	 * @param start
	 * @param len
	 * @return
	 */
	public static int getHexbit(byte value, int start, int len) {
		String hex = toHexString(value);
		hex = hex.substring(0, 1);
		int i = Integer.parseInt(hex, 16);
		return i;
	}

	/**
	 * 判断两个字节数组是否相等
	 * 
	 * @param array1
	 * @param array2
	 * @return
	 */
	public static boolean checkByteArray(byte[] array1, byte[] array2) {
		if (array1.length != array2.length) {
			return false;
		}
		for (int i = 0; i < array1.length; i++) {
			if (array1[i] != array2[i]) {
				return false;
			}
		}
		return true;
	}
	
	  /**
	   * 将指定字符串src，以每两个字符分割转换为16进制形式
	   * 如："2B44EFD9" --> byte[]{0x2B, 0x44, 0xEF, 0xD9}
	   * @param src String
	   * @return byte[]
	   */
	  public static byte[] HexString2Bytes(String src){
	    byte[] ret = new byte[src.length()/2];
	    byte[] tmp = src.getBytes();
	    for(int i=0; i<src.length()/2; i++){
	      ret[i] = uniteBytes(tmp[i*2], tmp[i*2+1]);
	    }
	    return ret;
	  }
	  
	  public static byte uniteBytes(byte src0, byte src1) {
		    byte _b0 = Byte.decode("0x" + new String(new byte[]{src0})).byteValue();
		    _b0 = (byte)(_b0 << 4);
		    byte _b1 = Byte.decode("0x" + new String(new byte[]{src1})).byteValue();
		    byte ret = (byte)(_b0 ^ _b1);
		    return ret;
		  }

	public static void main(String[] args) {
		byte b = (byte) 0xfa;
		String s = toBinaryString2(b);
		// System.out.println(s);

		int i = 7;
		byte[] tmp = integerToBytes(i << 1, false);
		System.out.println(ByteUtil.toHexString(tmp));
		/*byte a = 00;
		byte b = (byte) 0Xc8;
		int c = ByteUtil.bytesToInteger(String.valueOf(a+b));
		System.out.println(c);
		int fsd = c & 0xff;
		System.out.println(fsd);
		System.out.println(valueOf2byte(a,b));*/
		System.out.println("---------------------------------------------");
		byte ss = (byte) 0;
		byte ss1 = (byte) -56;
		byte[] bb = new byte[]{ss,ss1};
		String dsfs = toHexString(bb);
		BigInteger big = new BigInteger(dsfs,16);
		int xssd = big.intValue();
		System.out.println(xssd);
	}

}
